// gcc aff_demo3.c -lpthread -lm
// 
#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <math.h>
#include <errno.h>

#define handle_error_en(en, msg)\
    do { errno = en; perror(msg); exit(EXIT_FAILURE);} while (0);

void *cpu_intensive_function(void *args){
    float x = 1.5f;
    printf("thread id is %d\n", (int)pthread_self());
    printf("thread id is %d\n", getpid());
    while (1)
    {
        x *= sin(x) / atan(x) * tanh(x) * sqrt(x);
    }
}

int main(){

    // create a cpu set with core 1
    int blist[20]={1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39};
    cpu_set_t cpuset_1,cpuset_2,mask1,mask2,mask3;
    CPU_ZERO(&cpuset_1);
    CPU_ZERO(&cpuset_2);
    CPU_ZERO(&mask1);
    CPU_ZERO(&mask2);
    CPU_ZERO(&mask3);
	
    int i;
    for(i=0;i<20;i++){
        CPU_SET(blist[i], &cpuset_1);
        CPU_SET(blist[i]-1, &cpuset_2);
    }
      
    CPU_SET(38, &mask1);
    CPU_SET(39, &mask2);
    CPU_SET(33, &mask3);
    pthread_t th1;
    pthread_t th2;
    int ret1;
    int ret2;
    printf("main id is %d\n", getpid());
    sleep(15);
    printf("set main process aff \n");
    sched_setaffinity(0, sizeof(cpu_set_t), &mask3);
    sleep(15);
    printf("create threads \n");
    /* initialize threads */

    pthread_attr_t attr1,attr2;
    pthread_attr_init(&attr1);
    pthread_attr_init(&attr2);
    pthread_attr_setaffinity_np(&attr1, sizeof(cpu_set_t), &mask1);    
    pthread_attr_setaffinity_np(&attr2, sizeof(cpu_set_t), &mask2);
    

    ret1 = pthread_create(&th1, &attr1, cpu_intensive_function, NULL);
    ret2 = pthread_create(&th2, &attr2, cpu_intensive_function, NULL);
    
    /* Set the affinity to thread 1*/

    
//    printf("main id is %d\n", (int)pthread_self());
    printf("main id is %d\n", getpid());
    // wait for the threads to terminate.

    while(1){
	i=i*1;
    }
    pthread_join(th1, NULL);
    pthread_join(th2, NULL);

    return 0;
}
